/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pradoeditor;


import com.vlsolutions.swing.docking.DockGroup;
import com.vlsolutions.swing.docking.DockingConstants;
import com.vlsolutions.swing.docking.DockingDesktop;
import com.vlsolutions.swing.docking.RelativeDockablePosition;
import com.vlsolutions.swing.toolbars.ToolBarConstraints;
import com.vlsolutions.swing.toolbars.ToolBarContainer;
import com.vlsolutions.swing.toolbars.VLToolBar;
import java.awt.BorderLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JSeparator;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import pradoeditor.comun.ItemProject;
import pradoeditor.comun.constant.PrefixNameControls;
import pradoeditor.comun.BrowserLaunch;
import pradoeditor.comun.logger.CustomLogger;
import pradoeditor.controlbox.ControlBoxContainer;
import pradoeditor.databaseexplorer.DatabaseExplorer;
import pradoeditor.editors.Editor;
import pradoeditor.editors.EditorFactory;
import pradoeditor.editors.StartPage;
import pradoeditor.helpers.ProjectHelper;
import pradoeditor.loockandfeel.LookAndFeelChangedEventListener;
import pradoeditor.loockandfeel.LookAndFeelChangedEvent;
import pradoeditor.loockandfeel.LookAndFeelManager;
import pradoeditor.projectexplorer.RequestOpenItemEventListener;
import pradoeditor.projectexplorer.ProjectExplorer;
import pradoeditor.projectexplorer.RequestOpenItemEvent;
import pradoeditor.resources.text.MessagesCodes;
import pradoeditor.resources.text.MessagesManager;
import pradoeditor.wizard.project.ProjectCreatedEventListener;
import pradoeditor.wizard.project.ProjectOpenedEventListener;
import pradoeditor.wizard.project.ProjectCreatedEvent;
import pradoeditor.wizard.project.ProjectOpenedEvent;
import pradoeditor.wizard.project.WizardCreateProject;
import pradoeditor.wizard.project.WizardOpenProject;


/**
 *
 * @author jaimeg
 */
public class PradoEditor extends JFrame
{    

    // the desktop (which will contain dockables)
    DockingDesktop desk = new DockingDesktop();
    DockGroup docsGroup = new DockGroup("docs");
    
    ToolBarContainer tbContainer = ToolBarContainer.createDefaultContainer(true, true, true, true);
    VLToolBar fileToolBar = new VLToolBar("file");

    StartPage startPage = new StartPage();

    ProjectExplorer projectExplorer = new ProjectExplorer();
    ControlBoxContainer controlBoxContainer = new ControlBoxContainer();
    DatabaseExplorer databaseExplorer = new DatabaseExplorer();

    JMenuBar mb = new JMenuBar();

    String pathProject = null;
    
    public PradoEditor()
    {            
        tbContainer.add(desk, BorderLayout.CENTER);
        getContentPane().add(tbContainer, BorderLayout.CENTER);

        initWindow();
        initMenuBar();
        initToolBars();
        initDocks();
    }

    private void initWindow()
    {
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        setSize(toolkit.getScreenSize());
        setExtendedState(PradoEditor.MAXIMIZED_BOTH);

        setTitle(LABEL_TITLE);

        //Enlaces a los eventos de la pagina principal.
        addWindowListener(new WindowEventHandler());
    }

    /**
     * Procedimiento encargado en crear el Menu
    */
    private void initMenuBar()
    {
        setJMenuBar(mb);

        /* Menu Archivo */
        JMenu mnuFile=  new JMenu(LABEL_MENU_FILE);
        mb.add(mnuFile);

        /* Menu Nuevo Proyecto */
        JMenuItem mnuNewProject =  new JMenuItem(LABEL_MENU_NEW_PROJECT);
        mnuNewProject.addActionListener(new ActionListener(){
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                mnuNewProjectActionPerformed(evt);
            }
        });
        mnuFile.add(mnuNewProject);

        /* Menu Abrir Proyecto */
        JMenuItem mnuOpenProject =  new JMenuItem(LABEL_MENU_OPEN_PROJECT);
        mnuOpenProject.addActionListener(new ActionListener(){
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                mnuOpenProjectActionPerformed(evt);
            }
        });
        mnuFile.add(mnuOpenProject);

        /* Menu Separador */
        JSeparator mnuSeparatorFile1 = new JSeparator();
        mnuFile.add(mnuSeparatorFile1);

        /* Menu Salir */
        JMenuItem mnuExit =new JMenuItem(LABEL_MENU_EXIT);
        mnuExit.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                exit();
            }
        });
        mnuFile.add(mnuExit);

        /* Menu Herramientas */
        JMenu mnuTools =  new JMenu(LABEL_MENU_TOOLS);
        mb.add(mnuTools);

        /* Menu Look And Feel */
        JMenuItem mnuLoockAndFeel = new JMenuItem(LABEL_MENU_LOOK_AND_FEEL);
        mnuLoockAndFeel.addActionListener(new ActionListener(){
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                mnuLoockAndFeelActionPerformed(evt);
            }
        });
        mnuTools.add(mnuLoockAndFeel);

        /* Menu Ayuda */
        JMenu mnuHelp =  new JMenu(LABEL_MENU_HELP);
        mb.add(mnuHelp);

        /* Menu Pagina Oficial de PRADO */
        JMenuItem mnuOficialPage =  new JMenuItem(LABEL_MENU_PAGE_OFFICIAL_PRADO);
        mnuOficialPage.addActionListener(new ActionListener(){
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                mnuOficialPageActionPerformed(evt);
            }
        });
        mnuHelp.add(mnuOficialPage);
        
        /* Menu Separador */
        JSeparator mnuSeparatorHelp1 = new JSeparator();
        mnuHelp.add(mnuSeparatorHelp1);

        JMenuItem mnuRegister = new JMenuItem(LABEL_MENU_REGISTER);
        mnuRegister.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent evt) {
                mnuRegisterActionPerformed(evt);
            }
        });
        mnuHelp.add(mnuRegister);
    }

    /**
     * Procedimiento encargado en crear los botones del ToolBar
     */
    private void initToolBars()
    {
        tbContainer.getToolBarPanelAt(BorderLayout.NORTH).add(fileToolBar,new ToolBarConstraints(0,0));

        fileToolBar.add(createButton(LABEL_MENU_NEW_PROJECT , "NewProject.png"));
        fileToolBar.add(createButton(LABEL_MENU_OPEN_PROJECT, "OpenProject.png"));
        fileToolBar.add(createButton(LABEL_MENU_SAVE_ALL, "SaveAll.png"));
    }

    private void initDocks()
    {
        desk.addDockable(startPage);

        //desk.addHiddenDockable(projectExplorer, RelativeDockablePosition.RIGHT);
        projectExplorer.addRequestOpenItemEventListener(new RequestOpenItemEventListener()
        {
            public void OnRequestOpenItem(RequestOpenItemEvent evt)
            {
                openItem(evt.getItemProject());
            }
        });
        desk.split(startPage, projectExplorer, DockingConstants.SPLIT_RIGHT);

        desk.addHiddenDockable(controlBoxContainer, RelativeDockablePosition.LEFT);
        desk.addHiddenDockable(databaseExplorer, RelativeDockablePosition.RIGHT);
    }

    private JButton createButton(String name, String image)
    {
        JButton btn = new JButton();

        String nameControl = PrefixNameControls.jButton + name;

        btn.setName(nameControl);
        btn.setIcon(new ImageIcon(getClass().getResource("resources/icons/" + image)));
        btn.setToolTipText(name);
        btn.setMargin(new Insets(2,2,2,2));

        btn.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                toolBarActionPerformed(((JButton)e.getSource()).getName());
            }
        });

        return btn;
    }

    // <editor-fold defaultstate="collapsed" desc="Eventos del Menu">
    
    private void mnuNewProjectActionPerformed(java.awt.event.ActionEvent evt)
    {
        createProject();
    }

    private void mnuOpenProjectActionPerformed(java.awt.event.ActionEvent evt)
    {
        openProject();
    }    

    private void mnuOficialPageActionPerformed(java.awt.event.ActionEvent evt)
    {
        String url ="www.pradosoft.com";
        BrowserLaunch.openURL(url);
    }

    private void mnuLoockAndFeelActionPerformed (java.awt.event.ActionEvent evt)
    {
        LookAndFeelManager lockAndFeelManager = new LookAndFeelManager();

        lockAndFeelManager.addLockAndFeelChangedEventListener(new LookAndFeelChangedEventListener() {

            public void OnLockAndFeelChanged(LookAndFeelChangedEvent evt)
            {
                updateLookAndFeel(evt.getLookAndFeel());
            }
        });

        lockAndFeelManager.setLocationRelativeTo(this);
        lockAndFeelManager.setVisible(true);
    }

    private void mnuRegisterActionPerformed (java.awt.event.ActionEvent evt)
    {
        Register register = new Register(this, true);
        register.setLocationRelativeTo(this);
        register.setVisible(true);    
    }
    // </editor-fold>

    private void exit()
    {
        int reply = JOptionPane.showConfirmDialog(this, "Exit Application ?", "Confirm Exit", JOptionPane.YES_NO_OPTION);
        if (reply == JOptionPane.YES_OPTION)
        {
          System.exit(0);
        }
    }

    private void createProject ()
    {
        WizardCreateProject wizardProject = new WizardCreateProject(this, true);

        wizardProject.addProjectCreatedEventListener(new ProjectCreatedEventListener() {

            public void OnProjectCreated(ProjectCreatedEvent evt) {
                openProject(evt.getPath());
            }
        });

        wizardProject.setLocationRelativeTo(this);
        wizardProject.setVisible(true);
    }

    private void openProject()
    {
        WizardOpenProject wizardOpenProject = new WizardOpenProject(this, true);

        wizardOpenProject.addProjectOpenedEventListener(new ProjectOpenedEventListener() {

            public void OnProjectOpened(ProjectOpenedEvent evt) {
                openProject(evt.getPath());
            }
        });

        wizardOpenProject.setLocationRelativeTo(this);
        wizardOpenProject.setVisible(true);
    }

     private void openProject(String path)
     {
        ItemProject item = ProjectHelper.openProject(path);
        projectExplorer.setData(item);
        pathProject = path;
     }

    private void openItem(ItemProject itemProject)
    {
        Editor editor = EditorFactory.createEditor(itemProject);

        if (editor != null)
            desk.createTab(startPage, editor, 1, true);
        else
            JOptionPane.showMessageDialog(null, "Archivo no reconocido " + itemProject.getPath());
    }

    private void toolBarActionPerformed(String nameButton)
    {
        if (nameButton.equals(getNameButtonNew()))
            createProject();

        if (nameButton.equals(getNameButtonOpen()))
            openProject();
    }

    /***
     * Actualiza la apariencia del aplicativo.
     * @param lookAndFeel
     */
    private void updateLookAndFeel(LookAndFeel lookAndFeel)
    {
        try
        {
            UIManager.setLookAndFeel(lookAndFeel);
            SwingUtilities.updateComponentTreeUI(this);
            this.setExtendedState(PradoEditor.MAXIMIZED_BOTH);
        }
        catch (UnsupportedLookAndFeelException ex)
        {
            CustomLogger.writeError(this, ex);
        }
    }

    private String getNameButtonNew()
    {
        return PrefixNameControls.jButton + LABEL_MENU_NEW_PROJECT;
    }

    private String getNameButtonOpen()
    {
        return PrefixNameControls.jButton + LABEL_MENU_OPEN_PROJECT;
    }

    /***
     * Determina si el IDE tiene un proyecto abierto o no.
     * @return
     */
    public boolean isProjectOpen()
    {
        return pathProject != null;
    }

    // <editor-fold defaultstate="collapsed" desc="Metodo Main">
        public static void main(String[] args)
        {

            final PradoEditor frame = new PradoEditor();
            SwingUtilities.invokeLater(new Runnable() {
                // in the event dispatch thread

                public void run() {
                    frame.setVisible(true);
                }
            });
        }
    // </editor-fold>

        // <editor-fold defaultstate="collapsed" desc="Definicion de Mensajes">

        private final String LABEL_TITLE = MessagesManager.getMessage(MessagesCodes.pradoeditor_pradoeditor_LABEL_TITLE);
        private final String LABEL_MENU_FILE = MessagesManager.getMessage(MessagesCodes.pradoeditor_pradoeditor_LABEL_MENU_FILE);
        private final String LABEL_MENU_NEW_PROJECT = MessagesManager.getMessage(MessagesCodes.pradoeditor_pradoeditor_LABEL_MENU_NEW_PROJECT);
        private final String LABEL_MENU_OPEN_PROJECT = MessagesManager.getMessage(MessagesCodes.pradoeditor_pradoeditor_LABEL_MENU_OPEN_PROJECT);
        private final String LABEL_MENU_SAVE_ALL = MessagesManager.getMessage(MessagesCodes.pradoeditor_pradoeditor_LABEL_MENU_SAVE_ALL);
        private final String LABEL_MENU_EXIT = MessagesManager.getMessage(MessagesCodes.pradoeditor_pradoeditor_LABEL_MENU_EXIT);
        private final String LABEL_MENU_TOOLS = MessagesManager.getMessage(MessagesCodes.pradoeditor_pradoeditor_LABEL_MENU_TOOLS);
        private final String LABEL_MENU_LOOK_AND_FEEL = MessagesManager.getMessage(MessagesCodes.pradoeditor_pradoeditor_LABEL_MENU_LOOK_AND_FEEL);
        private final String LABEL_MENU_HELP = MessagesManager.getMessage(MessagesCodes.pradoeditor_pradoeditor_LABEL_MENU_HELP);
        private final String LABEL_MENU_PAGE_OFFICIAL_PRADO = MessagesManager.getMessage(MessagesCodes.pradoeditor_pradoeditor_LABEL_MENU_PAGE_OFFICIAL_PRADO);
        private final String LABEL_MENU_REGISTER = MessagesManager.getMessage(MessagesCodes.pradoeditor_pradoeditor_LABEL_MENU_REGISTER);

        // </editor-fold>
}
class WindowEventHandler extends WindowAdapter
{
  @Override
  public void windowClosing(WindowEvent evt) {
    System.exit(0);
  }
}